package com.starview.star.compiler.cafe;

import com.starview.platform.data.IArray;
import com.starview.star.compiler.Display;
import com.starview.star.compiler.ast.Abstract;
import com.starview.star.compiler.ast.Apply;
import com.starview.star.compiler.util.PrettyPrintDisplay;

public class CafeTypeDisplay extends Display
{
  public CafeTypeDisplay(PrettyPrintDisplay disp)
  {
    super(disp);
  }

  @Override
  public void visitApply(Apply trm)
  {
    if (CafeSyntax.isTypeVar(trm)) {
      appendWord(CafeSyntax.typeVarName(trm));
      IArray contracts = CafeSyntax.typeVarContracts(trm);
      if (contracts != null) {
        append(Names.REQUIRING);
        int mark = disp.markIndent(2);
        display(contracts, "{", ";\n", "}");
        disp.popIndent(mark);
      }
    } else if (CafeSyntax.isExistentialType(trm)) {
      CafeSyntax.existentialTypeVar(trm).accept(this);
      disp.append(Names.TILDA);
      CafeSyntax.existentialBoundType(trm).accept(this);
    } else if (CafeSyntax.isUniversalType(trm)) {
      CafeSyntax.universalBoundVar(trm).accept(this);
      disp.append(Names.TILDA);
      CafeSyntax.universalBoundType(trm).accept(this);
    } else if (CafeSyntax.isArrowType(trm)) {
      CafeSyntax.arrowTypeArgs(trm).accept(this);
      append(Names.ARROW);
      CafeSyntax.arrowTypeRes(trm).accept(this);
    } else if (CafeSyntax.isPatternType(trm)) {
      display(CafeSyntax.patternTypeArgs(trm), "(", ", ", ")");
      append(Names.LARROW);
      CafeSyntax.patternTypePtn(trm).accept(this);
    } else if (Abstract.arity(trm) == 0)
      appendName(Abstract.getOp(trm));
    else
      super.visitApply(trm);
  }
}
